home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr37
/
zfax223.zip
/
VCNVT.C
< prev
next >
Wrap
Text File
|
1993-06-26
|
12KB
|
320 lines
/**************************************************************************
VCNVT.C
Note : This file is for the voice file conversion between the ZyXEL 2, 3-bits
ADPCM format and the Sound Blaster .VOC file format. (9.6k sampling
uncompressed waveform)
Usage : vcnvt 0 sfile dfile
^ ^ ^
| | +--- Destination file path and name
| |
| +--- Source file path and name
|
+----- 0 : convert from .ZyXEL ADPCM to .VOC format
+----- 1 : convert from .VOC to ZyXEL 2 bits ADPCM format
+----- 2 : convert from .VOC to ZyXEL 3 bits ADPCM format
Created by Lin Chinru, Jan. 5, 1993. R&D Dep., ZyXEL Comm. Corp.
Copyright 1993, ZyXEL Communications Corporation
Updated by Javier Achirica.
**************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
#include <unistd.h>
#endif
void ToVoc(int) ;
void ToAdpcm(int) ;
void Quit(int,char *) ;
void Adaptive(char) ;
char Rcnt, CompBit ;
FILE *SourFh, *DestFh ;
int Rdata, EstMax, Delta, Data, Pack, RepCount ;
long BlkCnt, RepPos ;
int MaxTbl[] = { 0x399A, 0x3A9F, 0x4D14, 0x6607 } ;
/* ------------------------------------------------- */
/* Reserved buffers for the ZyXEL ADPCM file header */
/* ------------------------------------------------- */
char ZheadBuf0[16] ;
char ZheadBuf1[16] = { 'Z','y','X','E','L',2,0,0,0,0,0,0,0,0,0,0 } ;
/* ------------------------------------------ */
/* Reserved buffers for the .VOC file header */
/* ------------------------------------------ */
char VheadBuf0[32] ;
char VheadBuf1[32] = { 'C','r','e','a','t','i','v','e',' ',\
'V','o','i','c','e',' ','F','i','l','e',\
0x1a,0x1a,0,0x0a,1,0x29,0x11,\
1, 2, 0, 0, 0x98, 0 } ;
void main(int argc, char *argv[])
{
/* ---------- Open file and check for legality -------------- */
if ( argc!=4 || (*argv[1] < '0' || *argv[1] > '2') )
Quit(0,"") ;
if ( (SourFh=fopen(argv[2],"rb")) == NULL )
Quit(1,argv[2]) ;
if ( (DestFh=fopen(argv[3],"wb")) == NULL )
Quit(1,argv[3]) ;
/* ------------------ */
/* Initial parameters */
/* ------------------ */
Rdata = 0 ;
Rcnt = 8 ;
Delta = 5 ;
EstMax = 0 ;
BlkCnt = 2 ;
/* -------------------------------- */
/* ZyXEL ADPCM -> .VOC conversion */
/* -------------------------------- */
if ( *argv[1]=='0' ) {
fread( ZheadBuf0, sizeof(char), 16, SourFh) ;
if ( memcmp( ZheadBuf0, ZheadBuf1, 6) || ZheadBuf0[10]==0 )
Quit(2,argv[2]) ;
fwrite( VheadBuf1, sizeof(char), 32, DestFh) ;
CompBit = ZheadBuf0[10] ;
if ( CompBit == 1 ) {
MaxTbl[0] = 0x3800 ;
MaxTbl[1] = 0x5600 ;
}
while ( (Data=getc(SourFh)) != EOF ) {
if ( CompBit == 1 ) {
ToVoc((Data&0xc0)>>6) ; /* XX-- ---- */
ToVoc((Data&0x30)>>4) ; /* --XX ---- */
ToVoc((Data&0x0c)>>2) ; /* ---- XX-- */
ToVoc(Data&0x03) ; /* ---- --XX */
}
else {
ToVoc((Data&0xe0)>>5) ; /* XXX- ---- */
ToVoc((Data&0x1c)>>2) ; /* ---X XX-- */
Pack = (Data&0x03)<<1 ;
Data = getc(SourFh) ;
ToVoc(Pack|((Data&0x80)>>7)) ;
ToVoc((Data&0x70)>>4) ; /* -XXX ---- */
ToVoc((Data&0x0e)>>1) ; /* ---- XXX- */
Pack = (Data&0x01)<<2 ;
Data = getc(SourFh) ;
ToVoc(Pack|((Data&0xc0)>>6)) ;
ToVoc((Data&0x38)>>3) ; /* --XX X--- */
ToVoc(Data&0x07) ; /* ---- -XXX */
}
}
putc( 0, DestFh) ;
fseek( DestFh, 27, SEEK_SET ) ;
fwrite( &BlkCnt, 1, 3, DestFh ) ;
}
/* -------------------------------- */
/* .VOC -> ZyXEL ADPCM conversion */
/* -------------------------------- */
else {
fread( VheadBuf0, sizeof(char), 26, SourFh) ;
if ( memcmp( VheadBuf0, VheadBuf1, 22) )
Quit(2,argv[2]) ;
CompBit = *argv[1]-'0' ;
if ( CompBit == 1 ) {
MaxTbl[0] = 0x3800 ;
MaxTbl[1] = 0x5600 ;
}
ZheadBuf1[10] = CompBit ;
fwrite( ZheadBuf1, sizeof(char), 16, DestFh) ;
/* Pack = 0->terminator, 1->read sampling rate
2->read data, 3->silence, 6->repeat count,
7->end repeat, others->bypass */
while ( ((Pack=getc(SourFh))!=0) && (Pack!=EOF)) {
/* Read the block length */
fread( &BlkCnt, 1, 3, SourFh ) ;
/* Read the sampling rate, 9600 is required */
switch ( Pack )
{
case 1:
/* Data should be 8 bit at aprox. 9600 Hz */
fread( &Data, 1, 2, SourFh ) ;
if ( Data<147 || Data>157 )
Quit(2,argv[2]) ;
BlkCnt -= 2 ;
case 2:
for ( ; BlkCnt; --BlkCnt )
ToAdpcm( getc(SourFh) ) ;
break;
case 3:
fread( &BlkCnt, 1, 2, SourFh ) ;
BlkCnt *= 104 ;
BlkCnt /= 256 - getc(SourFh) ;
for ( ; BlkCnt; --BlkCnt )
ToAdpcm( 127 ) ;
break;
case 6:
fread( &RepCount, 1, 2, SourFh ) ;
BlkCnt -= 2;
RepPos = BlkCnt + ftell( SourFh ) ;
break;
case 7:
if ( RepCount )
{
--RepCount ;
if ( RepPos ) fseek( SourFh, RepPos - BlkCnt, SEEK_SET ) ;
}
}
fseek( SourFh, BlkCnt, SEEK_CUR ) ;
}
}
fclose(SourFh) ;
fclose(DestFh) ;
}
/**************************************************************************
ToVoc()
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void ToVoc(int Vdata)
{
int Wdata ;
Adaptive((char)Vdata) ;
if ( EstMax > 8191 )
Wdata = 8191 ;
else if ( EstMax < -8192 )
Wdata = -8192 ;
else
Wdata = EstMax ;
putc( ((Wdata>>6)+128)&0xff, DestFh ) ;
++BlkCnt ;
}
/**************************************************************************
ToAdpcm()
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void ToAdpcm(int Edata)
{
char TmpCompBit, DataBit ;
DataBit = 0 ;
Rdata &= 0xff00 ;
Edata -= 128 ;
Edata <<= 6 ;
Edata += 32 ;
/* Check for the waveform data and quantize this data */
if ( Edata -= EstMax ) {
TmpCompBit = 2*CompBit ;
/* ----------------------------------------------------- */
/* If the data is negative, set flag and change the sign */
/* ----------------------------------------------------- */
if ( Edata < 0 ) {
Edata = -Edata ;
DataBit = TmpCompBit ;
}
/* --------------------------------------------------- */
/* Quantize the waveform data, delta value is adaptive */
/* --------------------------------------------------- */
while ( ((Edata-=Delta)>0) && --TmpCompBit!=0 )
DataBit += 1 ;
/* ---------------------------- */
/* Rdata is the compressed data */
/* ---------------------------- */
Rdata |= ( DataBit << (7-CompBit) ) ;
}
/* ------------------------------------------------------ */
/* check if the compressed data can be pack into one byte */
/* ------------------------------------------------------ */
TmpCompBit = CompBit+1 ;
while ( TmpCompBit-- ) {
Rdata <<= 1 ;
if ( !(--Rcnt) ) {
putc(Rdata>>8,DestFh) ;
Rcnt = 8 ;
}
}
/* -------------------------------------- */
/* Adaptive the Delta and Estimat Maximum */
/* -------------------------------------- */
Adaptive(DataBit) ;
}
/**************************************************************************
Adaptive(DataBit, SignBit)
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void Adaptive(char DataBit)
{
int TmpMax ;
char SignBit ;
long TmpDelta ;
SignBit = DataBit & (2*CompBit) ;
DataBit &= ~(2*CompBit) ;
if ( (Delta&1) && !SignBit )
++EstMax ;
/* ------------------- */
/* Calculate the Delta */
/* ------------------- */
TmpDelta = Delta ;
TmpDelta *= MaxTbl[DataBit] ;
TmpDelta += 8192 ;
TmpDelta >>= 14 ;
/* -------------------- */
/* Calculate the EstMax */
/* -------------------- */
TmpMax = (Delta>>1) ;
while ( DataBit-- )
TmpMax += Delta ;
if ( SignBit )
EstMax -= TmpMax ;
else
EstMax += TmpMax ;
Delta = (int)TmpDelta ;
}
/**************************************************************************
Quit()
Copyright 1992, ZyXEL Communications Corporation
************************************************************************/
void Quit(int Num, char *MsgStr)
{
if ( Num == 0 ) {
printf("Usage : vcnvt 0 sfile dfile.\n");
printf(" ^ ^ ^\n") ;
printf(" │ │ └ Destination file\n");
printf(" │ └────── Source file\n") ;
printf(" └────────── Convert type : \n") ;
printf(" 0 : convert from .ZyXEL ADPCM to .VOC format.\n") ;
printf(" 1 : convert from .VOC to ZyXEL 2 bits ADPCM.\n") ;
printf(" 2 : convert from .VOC to ZyXEL 3 bits ADPCM.\n") ;
}
else if ( Num == 1 )
printf("Can't open %s\n", MsgStr) ;
else if ( Num == 2 )
printf("File format error on %s\n", MsgStr) ;
exit(1) ;
}